/** @jsxImportSource @emotion/react */
import {  Global } from "@emotion/react";
import React, {useContext, useEffect, useRef} from 'react';
import {PreloadedQuery, usePreloadedQuery} from 'react-relay/hooks';
import * as AuthCompQuery from "./__generated__/AuthCompQuery.graphql";
import UserContext from "./routing/UserContext";
import RoutingContext from "./routing/RoutingContext";
import {
    Button, ButtonRefComp, DarkMode, DarkRefMode,
    IconArrowRight, IconChevronDown,
    IconKey,
    LightMode, LightRefMode, MenuItem, MenuList,
    Navbar,
    Text,
    Toolbar,
    useTheme, MainMenuBar, IconTruck, DdMenu, DdMenuItem,
} from "customize-easy-ui-component";
import {Link as RouterLink} from "./routing/Link";
import food from "./images/food.svg";
import cutting_board_knife from "./images/cutting-board-knife.jpg";
import useLogoutMutation from "./common/useLogoutMutation";

import { ToastContainer } from 'react-toastify';
import "react-toastify/dist/ReactToastify.css";
import {EditStorageContext} from "./report/StorageContext";

//js 演示版import graphql from 'babel-plugin-relay/macro';可以的;
//ts版本只能这样;
const graphql = require("babel-plugin-relay/macro");

const { Suspense } = React;

//注意底下issueDetailQuery名字 要和上一级组件或路由器内的定义保证一样的。
//都要改的 PreloadedQuery<IssueDetailRootQuery.IssueDetailRootQuery> 类型也要改，import也该改。
interface Props {
    prepared: {
        rootQuery: PreloadedQuery<AuthCompQuery.AuthCompQuery>;
    }
    children: React.ReactNode;
}

//片段fragment 不可以重名，全局通用的。
//const fragment =graphql` fragment AuthComp_User on User { id,username,person{id,name} }`;


/** 主菜单条+用户鉴权；
 * 为了实现逻辑：浏览器直接输入URI但是已经有了token登录过了，就不要再次跳转login页面；允许没授权访问/free/页面。
 * 不得已，必须用GlobalState提供user提前验证，光光依靠AuthComp无法搞定逻辑！
 * GlobalState只会在SPA启动执行一趟的。假如token失效继续SPA内部Link跳转无法知晓{后端会报错}，AuthComp是补充机制：
 * 本组件AuthComp在路由表置顶就算在SPA内部Link跳转也必执行一次的，幸亏：内部缓存不会太勤快发起服务端认证的，不会真的都发送网络请求的；
 * AuthComp是每个路由点击都会执行。假如token超时了，auth验证通不过。
 * 路由方式，SPA点击路由进入新页面的：虽然AuthComp在路由表置顶必过，但是不会触发发送服务端请求包的，有缓存机制。
 * AuthComp和GlobalState缺一不可了。???看看能够搞定
 * 变化策略：直接在浏览器输入地址访问必须经过登录页面，就算刚刚已经登录有token了。
 * SPA刚起启动render两边才有user
 * 用户退出后，本组件也再次运行的，会暂时报错，需要强制刷新URL。
 * 【奇怪】因为Relay编译器自动编的？ 底下直接 fragment 添加 ...OneUserChoose_User 竟然允许直接用啊，不需要import ... ?。
 * 用户被后端删除的token无效连接后端失败！
 * */
export default function AuthComp(props: Props) {
    //const islogin=isLoginPage(history.location.pathname);
    // Defines *what* data the component needs via a query. The responsibility of
    // actually fetching this data belongs to the route definition: it calls
    // preloadQuery() with the query and variables, and the result is passed
    // on props.prepared.issuesQuery - see src/routes.ts
    //取数据比render（）还要早运行。数据准备好了，能避免折腾啊。一进来就已经有了数据，这跟apollo客户端不一样的。
    const data = usePreloadedQuery(
        graphql`
            query AuthCompQuery {
                authUser{
                    id,username, person{id,name}
                    dep{id name} office{id name} 
                    unit{id name dvs{id name} }
                    ispUnits{id,unit{id,name}}
                 }
            }
        `,
        props.prepared.rootQuery,
    );
    //data没有取到数据的，会直接报错，不会继续执行下去的。usePreloadedQuery没数据页面代码就没意义哦。

    //必须放入在当中useEffect{ } ； 否则setUser非法的！
    //login页面不对：竟然return null 两次，还没有执行useEffect里面代码，useEffect里面代码段是看着像独立运行的，useEffect运行时其它代码段没有执行，useEffect只管自己代码，
    const {authUser} = data;
    //第一次啊运行吗？
    const mountedRef = useRef(false);
    const {history } = useContext(RoutingContext);
    const theme = useTheme();
    //无需登录的URL
    const isPublic=isPublicAccsess(history.location.pathname);

    //刚加载render一边是没有user的，最快也要第二次render{地址栏进入模式、非SPA路由模式}。
    const {user, setUser} = useContext(UserContext);
    //必须 const 啊;  除非运行报错，否则后端非登录用户也会返回"{}"
    //后端鉴权接口函数auth() 时刻检查权限。 auth()应答是json转string,而不是全部的User账户属性字段;
    //const authjs=JSON.parse(auth);    //当前看到的用户
    if(!authUser)
    {
        // if(!isPublic)   window.location.href = "/login";   #调试屏蔽了
    }
    //console.log("AuthComp 目前render之后.mountedRef=", mountedRef.current,"user=",user);
    //这个useEffect的执行时间时机太奇怪了！！
    useEffect(() => {
        if(authUser) {
            if(!user)
                setUser(authUser);
            else {
                //简单判定
                if(JSON.stringify(user) !== JSON.stringify(authUser))
                    setUser(authUser);
            }
        }
    });

    //console.log("AuthComp see user=", user,"mountedRef.current=",mountedRef.current);
    if(!mountedRef.current) {
        mountedRef.current = true;
        //return null;重大毛病来源这里啊！！
    }
    else
    {
       // if(!user && !isPublic)
       //       window.location.href = "/login";  # 调试屏蔽
    }

    const { call:signOut } = useLogoutMutation();
    // const repContext=React.useContext(EditStorageContext) as any;       //【问题是】这里是无法捕获得到EditStorageContext
    // const {storage, setStorage, modified,setModified,} =repContext? repContext : {} as any;

    /** 原来这里也有：显示内容；｛最开始置顶的菜单？｝;要么前面的，要么最后面的，难道中间、难道多个子组件;
     * 路由特点：每一级层次都要留下render();
     * 这个页面不需要显示内容；但是要会跳转登录页面；遇到没有授权用户的并且不是无需要授权的路由页面。菜单不一定整个平台都通用一模一样，所以不要放在这里做。
     * ??第一次进入页面，若是已经登录了，不就没必要跳转登录页面了吗？
  【问题】本组件的执行进度不一定比其他路由组件更快，有可能用户直接在浏览器输入URL强制刷新的情况，user还没有准备好，儿孙组件却已经render()报错没有user;
     路由下一级似乎都会只有一个大组件包裹的，而不是多个组件并列的作为路由的下一级吧。
     下面{user: user,} 直接传递到二级路由器函数的参数prepare: (params:any) => {};路由这一层函数就能直接获取到用户数据。
     prepare｛｝：获取数据(在cb()触发函数中搞的)实际上在render()组件环境之外运行代码。
     若是使用这个 React.cloneElement(
        React.Children.only(props.children) as React.ReactElement<any>,
            {user: user}
     ) 用这个没法做得到，数据prepare在时间上走在render前面，不能从组件上解决，要出路由器的点击触发函数就得解决数据加载。时机滞后。
     */
    return (
    <React.Fragment>
        <Global
            styles={{
                html: {
                    overflowX: 'hidden',
                    [theme.mediaQueries.md]: {
                        backgroundAttachment: "fixed",
                        backgroundSize: "cover",
                        backgroundImage: `url(${cutting_board_knife})`
                    }
                }
            }}
        />

        <MainMenuBar  id={'floormenu'}  css={{
                justifyContent: "space-between",
                "@media print": {
                    display: 'none',
                }
            }}
        >
            {/*有可能窄屏幕情况，切分50%时在宽度上超出50%位置的；高度方向可能被按钮突破,Toolbar替代*/}
                <DdMenu label="菜单"  tight={true}
                        icon={
                            <ButtonRefComp
                                size="xs"
                                iconBefore={
                                    <img
                                        css={{
                                            marginRight: theme.spaces.sm,
                                            width: "25px",
                                            height: "25px"
                                        }}
                                        src={food} alt={''}
                                        aria-hidden
                                    />
                                }
                                variant="ghost"
                            >
                             我的
                            </ButtonRefComp>
                        }
                        divStyle={{
                            lineHeight: '1.0',
                        }}
                >
                    {user? <DdMenuItem label="账户" onClick={()=>signOut()}>退出帐户{user?.username}</DdMenuItem>
                        :
                        <DdMenuItem label="账户" onClick={() => { history.push("/login")}}>登录帐户</DdMenuItem>
                    }
                    <DdMenuItem label="首页" onClick={() => { history.push("/");
                    }}>首页</DdMenuItem>
                    <DdMenuItem label="设备" onClick={() => { history.push("/device");
                    }}>从设备入手</DdMenuItem>
                    <DdMenuItem label="单位" onClick={() => { history.push("/unit");
                    }}>从单位入手</DdMenuItem>
                    <DdMenuItem label="协议申请" onClick={() => { history.push("/agreements");
                    }}>协议受理申请</DdMenuItem>
                    <DdMenuItem label="特检头条" onClick={() => { history.push("/aide/Headlines");
                    }}>特检头条</DdMenuItem>
                    <DdMenu label="其余操作">
                        <DdMenuItem label="跳转上一代BS平台" />
                        <DdMenuItem label="跳转监察平台"
                                    onClick={ (e) => {
                                        console.log("Pressed!个网页2");
                                    } }
                        />
                        <DdMenuItem label="管道单元台账" onClick={() => { history.push("/pipingUnit");
                        }}>管道单元台账</DdMenuItem>
                        <DdMenuItem label="申请单" onClick={() => { history.push("/requests");
                        }}>申请单</DdMenuItem>
                    </DdMenu>
                </DdMenu>

            <Button
                size="xs"
                intent="primary"
                iconBefore={<IconArrowRight />}
                onPress={() => { history.push("/search/report")}}
            >
              搜索
            </Button>
            <Button
                size="xs"
                intent="primary"
                iconBefore={<IconChevronDown />}
                onPress={() => { history.push("/inspect")}}
            >
             检验
            </Button>
            <Button
                size="xs"
                intent="primary"
                iconBefore={
                    <img
                        css={{
                            marginRight: theme.spaces.sm,
                            width: "25px",
                            height: "25px"
                        }}
                        src={food} alt={''}
                        aria-hidden
                    />
                }
                onPress={() => { history.push("/zeebeTodo")}}
            >
             待办
            </Button>
            <RouterLink   href="/tasks">
                <Button
                    size="xs" noBind
                    intent="primary"
                    iconBefore={<IconKey />}
                >
                 任务
                </Button>
            </RouterLink>
        </MainMenuBar>

        <Suspense fallback={'Loading...'}>
            {props.children}
        </Suspense>

        <ToastContainer />
    </React.Fragment>
    );
}


//排除 不登录的人也允许访问
/**
 * 所有可以不需要登录就允许访问的URI
 * */
function  isPublicAccsess(path: string) {
    if(path === '/' || path.slice(0, 6) === '/free/' || path === '/login')
        return true;
    else
        return false;
}

